package net.larsan.dconf.util;

import static net.larsan.dconf.util.PropertiesUtil.toPropertyKey;
import static org.apache.commons.lang.Validate.notNull;

import java.util.Properties;

import net.larsan.dconf.DNode;
import net.larsan.dconf.DNodeVisitor;
import net.larsan.dconf.DPath;

/**
 * This node visitor exports the tree of nodes as 
 * a properties object.
 * 
 * @author Lars J. Nilsson
 */
public class PropertiesExporter implements DNodeVisitor {
	
	private final Properties target;
	private final boolean overwrite;
	
	private boolean recursive = true;
	private DPath root = null;

	public PropertiesExporter() {
		this(new Properties(), true);
	}
	
	/**
	 * @param target Properties to export to, must not be null
	 * @param overwrite True to overwrite existing properties, false otherwise
	 */
	public PropertiesExporter(Properties target, boolean overwrite) {
		notNull(target);
		this.target = target;
		this.overwrite = overwrite;
	}
	
	/**
	 * @return True if the exporter recurses down the child nodes, false otherwise
	 */
	public boolean isRecursive() {
		return recursive;
	}
	
	/**
	 * @param recursive True to recursively export children, false otherwise
	 */
	public void setRecursive(boolean recursive) {
		this.recursive = recursive;
	}
	
	/**
	 * @return The result properties set, never null
	 */
	public Properties getTarget() {
		return target;
	}

	@Override
	public void visit(DNode node) {
		if(root == null) {
			root = node.getPath();
		}
		// get node key delimited by '.'
		String key = toPropertyKey(root, node.getPath());
		for (String name : node.getAttributes().keySet()) {
			String val = node.getAttribute(name);
			// append attribute to key, check for root (zero length name)
			String fullKey = (key.length() == 0 ? name : key + "." + name);
			if(overwrite || !target.contains(fullKey)) {
				// if it doesn't exist, or we're overwriting
				target.setProperty(fullKey, val);
			}
		}
		if(recursive) {
			// recurse down children
			for (DNode child : node.getChildren()) {
				visit(child);
			}
		}
	}
}
